import akka.actor.AbstractActor
import akka.actor.ActorRef
import akka.actor.Props
import com.google.protobuf.MessageLite
import io.netty.bootstrap.Bootstrap
import io.netty.channel.Channel
import robotAi.FAILED
import robotAi.RUNNING
import robotAi.Robot
import robotAi.RobotAction
import xhhx.network.C2sMsg

class RobotActor(var b: Bootstrap, var robot: Robot) : AbstractActor() {
    companion object {
        fun props(b: Bootstrap, robot: Robot): Props {
            return Props.create(RobotActor::class.java, b, robot);
        }
    }

    private var ai: RobotAction<Robot> = robot.aiFun.invoke()
    private var isFinish = false
    private var isConnect = false
    private lateinit var ch: Channel

    class MsgResponder(val msgID: Int, val receive: MessageLite)

    class Run()

    override fun createReceive(): Receive {
        return receiveBuilder()
                .match(Run::class.java) {
                    run()
                }
                .match(MsgResponder::class.java) { msg ->
                    rec(msg.msgID, msg.receive)
                }
                .build()
    }

    private fun run() {
        if (isFinish) {
            return
        }
        if (!isConnect) {
            var future = b.connect(TARGET_IP, TARGET_PORT)
            ch = future.channel()
            robot.ch = ch
            countRef.tell(CountActor.ConnectMsg(ch, self()), ActorRef.noSender())
            isConnect = true
        } else {
            update()
        }
    }

    private fun update() {
        val result = ai.Run(robot)
        if (result != RUNNING) {
            if (result == FAILED){
                println("RobotId:${robot.id} Failed" )
            }

            Finish()
        }
    }

    private fun rec(msgId: Int, msg: MessageLite) {
        ai.ReceiveMessage(C2sMsg(msgId, msg))
    }

    private fun Finish() {
        isFinish = true
        ch.close()
        countRef.tell(CountActor.DelMsg(), ActorRef.noSender())
    }
}